package com.zhaotianhao.serviceproduct.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhaotianhao.serviceproduct.api.SkuStockApi;
import com.zhaotianhao.serviceproduct.dto.SkuStockDto;
import com.zhaotianhao.serviceproduct.dto.SpuQueryDTO;
import com.zhaotianhao.serviceproduct.entity.*;
import com.zhaotianhao.serviceproduct.mapper.SpuMapper;
import com.zhaotianhao.serviceproduct.service.*;
import com.zhaotianhao.serviceproduct.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * spu表，该表描述的是一个抽象性的商品，比如 iphone8 服务实现类
 * </p>
 *
 * @author Z-7
 * @since 2022-04-27
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements ISpuService {
    @Autowired
    private SkuStockApi skuStockApi;
    @Autowired
    private ISkuService iSkuService;
    @Autowired
    private IBrandService iBrandService;
    @Autowired
    private ICategoryService iCategoryService;
    @Autowired
    private ISpuDetailService iSpuDetailService;
    @Autowired
    private ISpecGroupService iSpecGroupService;
    @Autowired
    private ISpecParamService iSpecParamService;

    /**
     * spu列表的查询
     *
     * @param spuQueryDTO 搜索内容
     * @param pageNum     起始页
     * @param pageSize    偏移量
     * @return
     */
    @Override
    public PageInfo<SpuListVO> getPageInfo(SpuQueryDTO spuQueryDTO, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<SpuListVO> list = getBaseMapper().queryList(spuQueryDTO);
        return new PageInfo<>(list);
    }

    /**
     * 单个商品详情
     *
     * @param skuId
     * @return
     */
    @Override
    public SkuDetailVO getSkuBySkuId(long skuId) {

        SkuDetailVO skuDetailVO = getSkuDetailVO(skuId);

        List<SpecParam> specParams = iSpecParamService.queryAllSpecParam();

        /*------------------设置私有属性-------------------*/
        // 将sku json转为map
        LinkedHashMap linkedHashMap = JSONObject.parseObject(iSkuService.getById(skuId).getOwnSpec(), LinkedHashMap.class);
        skuDetailVO.setGroupVOS(setGroupVOS(specParams, linkedHashMap));

        /*------------------设置通用属性-------------------*/
        QueryWrapper<SpuDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("spu_id", iSkuService.getById(skuId).getSpuId());
        SpuDetail spuDetail = iSpuDetailService.getOne(queryWrapper);

        skuDetailVO.setGenericVOS(setGenericVO(spuDetail, specParams));

        /*------------------设置特殊属性-------------------*/
        skuDetailVO.setSpecialVOS(setSpecialVO(spuDetail, specParams));

        /*------------------设置库存量-------------------*/
        SkuStockDto skuStockDto = skuStockApi.getStockBySkuId(skuDetailVO.getId());
        Long totalStock = skuStockDto.getTotalStock();
        Long occupyStock = skuStockDto.getOccupyStock();
        skuDetailVO.setStock(totalStock - occupyStock);

        return skuDetailVO;
    }

    /**
     * 设置特殊属性
     * @param spuDetail  spu 详情
     * @param specParams 所有的规格参数
     * @return 特殊的规格
     */
    public List<SpecialVO> setSpecialVO(SpuDetail spuDetail,List<SpecParam> specParams) {
        LinkedHashMap specialSpecMap = JSONObject.parseObject(spuDetail.getSpecialSpec(), LinkedHashMap.class);
        //特殊属性
        List<SpecialVO> specialVOS = new ArrayList<>();
        for (Object id : specialSpecMap.keySet()) {
            // object 要转Long 需要先转String
            String key = (String) id;
            SpecialVO specialVO = new SpecialVO();
            // 查询并设置属性名
            specParams.forEach(specParam->{
                //如果当前的参数id等于json中的id
                if (specParam.getId() == Long.parseLong(key)) {
                    // 设置VO对象中的 name值 所属组
                    specialVO.setName(specParam.getName());
                }
            });
            // 设置对应的值
            Object o = specialSpecMap.get(id);
            String[] strings = JSONObject.parseObject(o.toString(), String[].class);
            specialVO.setValues(strings);
            specialVOS.add(specialVO);
        }
        // 设置特殊属性数组
        return specialVOS;
    }

    /**
     * 设置通用属性
     * @param spuDetail  spu 详情
     * @param specParams 所有的规格参数
     * @return 通用的规格
     */
    public List<GenericVO> setGenericVO(SpuDetail spuDetail,List<SpecParam> specParams) {
        //通用属性
        List<GenericVO> genericVOS = new ArrayList<>();
        // sku规格组集合
        List<SpecGroup> specGroupList = new ArrayList<>();
        // 所以规格组
        List<SpecGroup> list = iSpecGroupService.list();
        // 规格组需要的参数
        List<SpecParamVO> specParamVOList = new ArrayList<>();
        // 通用属性json转为有序map
        LinkedHashMap genericMap = JSONObject.parseObject(spuDetail.getGenericSpec(), LinkedHashMap.class);
        for (Object id : genericMap.keySet()) {
            // object 要转Long 需要先转String
            String key = (String) id;
            GenericVO genericVO = new GenericVO();
            // 参数规格VO  并设置id value加入集合
            SpecParamVO specParamVO = new SpecParamVO();
            specParamVO.setId(Long.parseLong(key));
            specParamVO.setValue(genericMap.get(id).toString());
            specParams.forEach(specParam->{
                //如果当前的参数id等于json中的id
                if (specParam.getId() == Long.parseLong(key)) {
                    // 设置VO对象中的 name值 所属组
                    specParamVO.setName(specParam.getName()).setGroupId(specParam.getGroupId());
                }
            });
            // 得到所有的sku 特殊参数 插入集合
            specParamVOList.add(specParamVO);
        }
        for (SpecGroup group : list) {
            for (SpecParamVO specParamVO : specParamVOList) {
                if (group.getId().equals(specParamVO.getGroupId())) {
                    specGroupList.add(group);
                }
            }
        }
        // 获取对应的参数分组进行去重 并转换成VO对象
        List<SpecGroup> collect = specGroupList.stream().distinct().collect(Collectors.toList());
        collect.forEach(item ->{
            GenericVO genericVO = new GenericVO();
            BeanUtils.copyProperties(item,genericVO);
            genericVOS.add(genericVO);
        });
        genericVOS.forEach(item->{
            //规格参数中的组id和当前遍历id相等的所有数据转成集合
            item.setParamVOS(specParamVOList.stream().filter(spec->Objects.equals(item.getId(),spec.getGroupId())).collect(Collectors.toList()));
        });
        // 为sku 通用属性赋值
        return genericVOS;
    }

    /**
     * 设置私有属性
     * @param specParams 所有的规格参数
     * @param groupVOSMap json串
     * @return SkuDetailVO对象
     */
    @Override
    public List<SpecGroupVO> setGroupVOS(List<SpecParam> specParams, LinkedHashMap groupVOSMap) {
        // 规格组需要的参数
        List<SpecParamVO> specParamVOList = new ArrayList<>();
        // sku规格组集合
        List<SpecGroup> specGroupList = new ArrayList<>();
        // 所以规格组
        List<SpecGroup> list = iSpecGroupService.list();
        // sku规格组集合
        List<SpecGroupVO> specGroupVOList = new ArrayList<>();

        for (Object id : groupVOSMap.keySet()) {
            // object 要转Long 需要先转String
            String key = (String) id;
            // 参数规格VO  并设置id value加入集合
            SpecParamVO specParamVO = new SpecParamVO();
            specParamVO.setId(Long.parseLong(key));
            specParamVO.setValue(groupVOSMap.get(id).toString());
            specParams.forEach(specParam->{
                //如果当前的参数id等于json中的id
                if (specParam.getId() == Long.parseLong(key)) {
                    // 设置VO对象中的 name值 所属组
                    specParamVO.setName(specParam.getName()).setGroupId(specParam.getGroupId());
                }
            });
            // 得到所有的sku 特殊参数 插入集合
            specParamVOList.add(specParamVO);
        }
        for (SpecGroup group : list) {
            for (SpecParamVO specParamVO : specParamVOList) {
                if (group.getId().equals(specParamVO.getGroupId())) {
                    specGroupList.add(group);
                }
            }
        }
        // 获取对应的参数分组进行去重 并转换成VO对象
        List<SpecGroup> collect = specGroupList.stream().distinct().collect(Collectors.toList());
        collect.forEach(item ->{
            SpecGroupVO specGroupVO = new SpecGroupVO();
            BeanUtils.copyProperties(item,specGroupVO);
            specGroupVOList.add(specGroupVO);
        });
        specGroupVOList.forEach(item->{
            //规格参数中的组id和当前遍历id相等的所有数据转成集合
            item.setParamVOS(specParamVOList.stream().filter(spec->Objects.equals(item.getId(),spec.getGroupId())).collect(Collectors.toList()));
        });

        return specGroupVOList;
    }

    @Override
    public SkuDetailVO getSkuDetailVO(Long skuId) {
        SkuDetailVO skuDetailVo = new SkuDetailVO();
        Sku sku = iSkuService.getById(skuId);
        BeanUtil.copyProperties(sku,skuDetailVo);

        //查询商品基本信息
        Spu spu = getById(sku.getSpuId());
        SpuDetail spuDetail = iSpuDetailService.getById(sku.getSpuId());
        //查询品牌名称
        Brand brand = iBrandService.getById(spu.getBrandId());
        skuDetailVo.setBrandName(brand.getName());

        //spu包装信息 售后信息
        skuDetailVo.setAfterService(spuDetail.getAfterService());
        skuDetailVo.setPackingList(spuDetail.getPackingList());

        //查询分类信息
        Category category1 = iCategoryService.getById(spu.getCid1());
        Category category2 = iCategoryService.getById(spu.getCid2());
        Category category3 = iCategoryService.getById(spu.getCid3());
        skuDetailVo.setCid1Name(category1.getName());
        skuDetailVo.setCid2Name(category2.getName());
        skuDetailVo.setCid3Name(category3.getName());
        skuDetailVo.setCid3(category3.getId());
        return skuDetailVo;
    }
}
